#include "UDPReceiver.h"
#include "ConfigManager.h"

UDPReceiver::UDPReceiver() :
	_thread(NULL)
{
}

UDPReceiver::~UDPReceiver()
{
	if (_thread != NULL)
		delete _thread;
}

//Todo : reinitialize when network config changed.....
bool UDPReceiver::Initialize()
{
	bool init = false;
	if (_thread == NULL)
		_thread = new QThread;
	if (_thread != NULL)
	{
		connect(&_socket, SIGNAL(readyRead()), this, SLOT(ReadDatagram()));
		if (Bind(GroupA) &&
			Bind(GroupB) &&
			Bind(GroupC) &&
			Bind(GroupD) &&
			Bind(GroupE) &&
			Bind(GroupF) &&
			Bind(CONFIG_MANAGER->GetNetworkPort()))
		{
			moveToThread(_thread);
			_thread->start();
			init = true;
		}
	}
	return init;
}

bool UDPReceiver::Bind(int port)
{
	_socket.abort();
	return _socket.bind(QHostAddress::Any, port, QUdpSocket::ShareAddress);
}

void UDPReceiver::ReadDatagram()
{
	QByteArray dgram;
	QHostAddress addr;
	while (_socket.hasPendingDatagrams())
	{
		int length = _socket.pendingDatagramSize();
		if (length != -1)
		{
			dgram.resize(length);
			if (_socket.readDatagram(dgram.data(), dgram.size(), &addr) == length)
			{
				UDPPacket *packet = new UDPPacket;
				if (packet != NULL)
				{
					packet->dgram = dgram;
					packet->addr = addr;
					emit sigDatagramReceived(packet);
				}
			}
			else
				qDebug() << "readDatagram() error";
		}
		else
			qDebug() << "not enough pending datagram size";
	}
}

static UDPReceiver g_udpReceiver;
UDPReceiver *GetUDPReceiver()
{
	return &g_udpReceiver;
}
